package me.realirea.listener;

import me.pleens.awals.annotation.event.EventListener;
import me.pleens.awals.api.lang.LanguageManager;
import me.realirea.api.TombstoneManager;
import me.realirea.api.event.TombstoneBreakEvent;
import me.realirea.config.TombstoneConfig;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.inventory.ItemStack;

import javax.inject.Inject;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 监听玩家的一些操作
 */
@EventListener
public class PlayerListener implements Listener {

    private final TombstoneConfig tombstoneConfig;
    private final TombstoneManager tombstoneManager;
    private final LanguageManager languageManager;

    /**
     * 玩家监听器
     *
     * @param tombstoneConfig  墓碑配置
     * @param tombstoneManager 墓碑管理
     * @param languageManager  语言管理
     */
    @Inject
    public PlayerListener(TombstoneConfig tombstoneConfig, TombstoneManager tombstoneManager, LanguageManager languageManager) {
        this.tombstoneConfig = tombstoneConfig;
        this.tombstoneManager = tombstoneManager;
        this.languageManager = languageManager;
    }

    /**
     * 处理玩家死亡
     *
     * @param event 玩家死亡事件
     */
    @EventHandler
    public void onPlayerDeath(final PlayerDeathEvent event) {
        // 如果 keep inventory 开启则直接跳过处理
        if (event.getKeepInventory()) {
            return;
        }

        Player player = event.getEntity();
        if (player.hasPermission("tombstone.bypass")) {
            return;
        }

        World world = player.getWorld();
        if (!tombstoneConfig.getEnableWorld().isEmpty() && !tombstoneConfig.containsEnableWorld(world.getName())) {
            return;
        }

        Location location = player.getLocation();
        if (location.getBlock().getType().isSolid()) {
            for (int blockY = location.getBlockY(); blockY < world.getMaxHeight(); blockY++) {
                location.setY(blockY);
                Block block = location.getBlock();
                if (!block.getType().isSolid()) {
                    tombstoneManager.generateTombstone(player, block, event.getDrops());
                    event.getDrops().clear();
                    return;
                }
            }
        } else {
            // 从当前位置向下扫描 直到找到完整方块
            for (int blockY = location.getBlockY(); blockY > world.getMinHeight() - 1; blockY--) {
                location.setY(blockY);
                Block block = location.getBlock();
                if (block.getType().isSolid()) {
                    tombstoneManager.generateTombstone(player, block.getRelative(BlockFace.UP), event.getDrops());
                    event.getDrops().clear();
                    return;
                }
            }
        }
        location.setY(world.getMinHeight());
        Block block = location.getBlock();
        block.setType(Material.COBBLESTONE);
        tombstoneManager.generateTombstone(player, block.getRelative(BlockFace.UP), event.getDrops());
        event.getDrops().clear();
    }

    /**
     * 处理方块被破坏
     *
     * @param event 方块破坏事件
     */
    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
    public void onBlockBreak(final BlockBreakEvent event) {
        Block relative = event.getBlock().getRelative(BlockFace.UP);
        if (relative.getState() instanceof Sign sign && tombstoneManager.isTombstone(sign)) {
            event.setCancelled(true);
            languageManager.sendMessage("tombstone.below.protect", event.getPlayer());
            return;
        }
        if (event.getBlock().getState() instanceof Sign sign && tombstoneManager.isTombstone(sign)) {
            TombstoneBreakEvent tombstoneBreakEvent = tombstoneManager.callTombstoneBreakEvent(event.getPlayer(), sign);
            if (tombstoneBreakEvent.isCancelled()) {
                event.setCancelled(true);
                return;
            }
            // 刷木牌? 不存在的
            event.setDropItems(false);
            // 如果墓碑被挖掘 将陪葬品掉落到地面
            Block block = tombstoneBreakEvent.getBlock();
            Location location = block.getLocation();
            for (ItemStack itemStack : tombstoneBreakEvent.getFuneral()) {
                block.getWorld().dropItemNaturally(location, itemStack);
            }
            Player player = tombstoneBreakEvent.getPlayer();
            OfflinePlayer deceased = tombstoneBreakEvent.getDeceased();
            // 如果被盗墓发送提示信息
            if (deceased.isOnline() && !player.getUniqueId().equals(deceased.getUniqueId())) {
                Map<String, Object> map = new HashMap<>(5);
                map.put("world", block.getWorld().getName());
                map.put("x", location.getBlockX());
                map.put("y", location.getBlockY());
                map.put("z", location.getBlockZ());
                map.put("grave_robber", event.getPlayer().getName());
                languageManager.sendMessage("tombstone.stolen", Objects.requireNonNull(deceased.getPlayer()), map);
            }
        }
    }
}
